//
// Created by shen on 2024/10/30.
//


#include "SDLRender.h"

SDLRender::SDLRender():VideoRender(VIDEO_RENDER_SDL) {

}
void SDLRender::UnInit() {
    SDL_DestroyRenderer(renderer);
    SDL_Quit();
}


SDLRender::~SDLRender() noexcept {



}

void SDLRender::RenderVideoFrame(AVFrame *pImage) {
    SDL_Rect rect;
    rect.x = 0;
    rect.y = 0;
    rect.w = width;
    rect.h = height;
    // Use this function to update a rectangle within a planar
    // YV12 or IYUV texture with new pixel data.
   int renter= SDL_UpdateTexture(
            texture,            // the texture to update
            &rect,              // a pointer to the rectangle of pixels to update, or NULL to update the entire texture
            pImage->data[0],      // the raw pixel data for the Y plane
            pImage->linesize[0]
    );

    printf("render renter %d",renter);
    // clear the current rendering target with the drawing color
    SDL_RenderClear(renderer);

    // copy a portion of the texture to the current rendering target
    SDL_RenderCopy(
            renderer,   // the rendering context
            texture,    // the source texture
            NULL,       // the source SDL_Rect structure or NULL for the entire texture
            NULL        // the destination SDL_Rect structure or NULL for the entire rendering
            // target; the texture will be stretched to fill the given rectangle
    );

    // update the screen with any rendering performed since the previous call
    SDL_RenderPresent(renderer);

}
void SDLRender::RenderVideoFrame(NativeImage *pImage) {

    SDL_Rect rect;
    rect.x = 0;
    rect.y = 0;
    rect.w = width;
    rect.h = height;
    // Use this function to update a rectangle within a planar
    // YV12 or IYUV texture with new pixel data.
    SDL_UpdateYUVTexture(
            texture,            // the texture to update
            &rect,              // a pointer to the rectangle of pixels to update, or NULL to update the entire texture
            pImage->ppPlane[0],      // the raw pixel data for the Y plane
            pImage->pLineSize[0],  // the number of bytes between rows of pixel data for the Y plane
            pImage->ppPlane[1],      // the raw pixel data for the U plane
            pImage->pLineSize[1],  // the number of bytes between rows of pixel data for the U plane
            pImage->ppPlane[2],      // the raw pixel data for the V plane
            pImage->pLineSize[2]   // the number of bytes between rows of pixel data for the V plane
    );

    // clear the current rendering target with the drawing color
    SDL_RenderClear(renderer);

    // copy a portion of the texture to the current rendering target
    SDL_RenderCopy(
            renderer,   // the rendering context
            texture,    // the source texture
            NULL,       // the source SDL_Rect structure or NULL for the entire texture
            NULL        // the destination SDL_Rect structure or NULL for the entire rendering
            // target; the texture will be stretched to fill the given rectangle
    );

    // update the screen with any rendering performed since the previous call
    SDL_RenderPresent(renderer);

}

void SDLRender::Init(int videoWidth, int videoHeight, int *dstSize) {
    ret = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);   // [1]
    if (ret != 0)
    {
        // error while initializing SDL
        printf("Could not initialize SDL - %s\n.", SDL_GetError());
        // exit with error
        return;
    }

    // Create a window with the specified position, dimensions, and flags.
    SDL_Window * screen = SDL_CreateWindow( // [2]
            "SDL Video Player",
            SDL_WINDOWPOS_UNDEFINED,
            SDL_WINDOWPOS_UNDEFINED,
            videoWidth/2,
            videoHeight/2,
            SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI
    );

    if (!screen)
    {
        // could not set video mode
        printf("SDL: could not set video mode - exiting.\n");

        // exit with Error
        return;
    }

    //swap buffer
    SDL_GL_SetSwapInterval(1);

    // A structure that contains a rendering state.


    // Use this function to create a 2D rendering context for a window.
    renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE);

    // A structure that contains an efficient, driver-specific representation
    // of pixel data.


    // Use this function to create a texture for a rendering context.
    texture = SDL_CreateTexture(  // [4]
            renderer,
            SDL_PIXELFORMAT_RGB24,
            SDL_TEXTUREACCESS_STREAMING,
            videoWidth,
            videoHeight
    );


}